﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using Microsoft.Practices.Unity;
using TorchView.SharedStashEditor.Models;
using TorchView.Game;
using TorchView.Composition;
using TorchView.SharedStashEditor.Helpers;
using TorchView.Windows;
using System.Windows.Input;
using System.Windows;
using TorchView.SharedStashEditor.Views;
using TorchView.GameContent.Affixes;

namespace TorchView.SharedStashEditor.ViewModels
{
    public class InventoryViewModel<T> : INotifyPropertyChanged where T : struct, IComparable, IConvertible, IFormattable 
    {
        private IUnityContainer _Container;
        private ItemCollection _collections;

        public InventoryViewModel(IUnityContainer container)
        {
            _Container = container;

            _collections = ItemCollection.DefaultCollection;

            _AddItemCommand = new DirectCommand(ExecuteAddItem, ItemNotSelected);
            _RemoveItemCommand = new DirectCommand(ExecuteRemoveItem, ItemSelected);
        }

        private bool ItemSelected(object parameter)
        {
            if (_selectedSlot == null)
            {
                return false;
            }
            else
            {
                return _selectedSlot.HasItem;
            }
        }

        private bool ItemNotSelected(object parameter)
        {
            if (_selectedSlot == null)
                return false;
            else
            {
                return !_selectedSlot.HasItem;
            }
        }

        private void ExecuteAddItem(object parameter)
        {
            if (_selectedSlot != null)
            {
                var viewModel = _Container.Resolve<IAddItemViewModel>(new PropertyOverride("Owner", Application.Current.MainWindow));
                viewModel.Items.Load();
                if (viewModel.View.ShowDialog() ?? false)
                {
                    long itemId = viewModel.ItemId;

                    GameContent.Units.Item itemRef = _collections[itemId];

                    if (itemRef != null)
                    {
                        Item item = new Item();
                        item.ItemModelID = itemId;
                        item.Name = itemRef.DisplayName;
                        item.InventorySlot = _selectedSlot.UInt;
                        _selectedSlot.setItem(item);
                        ItemViewModel itemVM = _selectedSlot.Item;
                        foreach (GameContent.Units.Effect itemEffect in itemRef.Effects)
                        {
                            itemVM.AttachEffect(itemEffect);
                        }
                        foreach (string affixName in itemRef.Affixes)
                        {
                            Affix affix = AffixItemList.DefaultList[affixName];
                            if (affix != null)
                            {
                                foreach (GameContent.Units.Effect affixEffect in affix.Effects)
                                {
                                    itemVM.AttachEffect(affixEffect);
                                }
                            }
                        }
                        itemVM.Save();

                        ItemList.Add(item);

                        ItemSlot.Refresh(); //Refresh List
                        _AddItemCommand.RequeryCanExecute(); //Refresh Add Item Button
                        _RemoveItemCommand.RequeryCanExecute();
                    }
                }
            }
        }

        private void ExecuteRemoveItem(object parameter)
        {
            if (_selectedSlot != null && _selectedSlot.HasItem)
            {
                if (_Container.Resolve<IMessageBoxService>().Show(Application.Current.MainWindow, string.Format("Are you sure you want to remove {0}?", _selectedSlot.Item), "Confirm Delete", MessageBoxButton.YesNo, MessageBoxImage.Warning, MessageBoxResult.No) == MessageBoxResult.Yes)
                {
                    Item item = _selectedSlot.Item.InnerItem;
                    ItemList.Remove(item);
                    _selectedSlot.setItem(null);

                    ItemSlot.Refresh(); //Refresh List
                    _AddItemCommand.RequeryCanExecute(); //Refresh Add Item Button
                    _RemoveItemCommand.RequeryCanExecute();
                }
            }
        }

        #region Commands
        private DirectCommand _AddItemCommand;
        public ICommand AddItemCommand { get { return _AddItemCommand; } }

        private DirectCommand _RemoveItemCommand;
        public ICommand RemoveItemCommand { get { return _RemoveItemCommand; } }
        #endregion

        #region Properties
        public ObservableCollection2<ItemSlot<T>> ItemSlot { get; set; }
        public List<Item> ItemList { get; set;}

        private ItemSlot<T> _selectedSlot = null;
        public ItemSlot<T> SelectedSlot
        {
            get { return _selectedSlot; }
            set
            {
                _selectedSlot = value;
                _AddItemCommand.RequeryCanExecute(); //Refresh Add Item Button
                _RemoveItemCommand.RequeryCanExecute();
            }
        }
        #endregion


        #region INotifyPropertyChanged Members
        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
        #endregion
    }
}
